package com.hedl.classroom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hedl.classroom.base.exception.OnlinecClassroomException;
import com.hedl.classroom.base.model.PageResult;
import com.hedl.classroom.dto.MyCourseTableParams;
import com.hedl.classroom.dto.XcChooseCourseDto;
import com.hedl.classroom.dto.XcCourseTablesDto;
import com.hedl.classroom.feignclient.ContentServiceClient;
import com.hedl.classroom.mapper.XcChooseCourseMapper;
import com.hedl.classroom.mapper.XcCourseTablesMapper;
import com.hedl.classroom.model.po.CoursePublish;
import com.hedl.classroom.po.XcChooseCourse;
import com.hedl.classroom.po.XcCourseTables;
import com.hedl.classroom.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Big Watermelon
 * @description 选课接口相关实现
 * @date 2023/12/16/14:39
 */
@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

    @Resource
    private XcChooseCourseMapper xcChooseCourseMapper;

    @Resource
    private XcCourseTablesMapper xcCourseTablesMapper;

    @Resource
    private ContentServiceClient contentServiceClient;

    @Transactional
    @Override
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {

        //选课调用内容管理查询课程的收费规则
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        if (coursepublish == null){
            OnlinecClassroomException.cast("课程不存在!");
        }
        //收费规则
        String charge = coursepublish.getCharge();
        //选课记录
        XcChooseCourse xcChooseCourse = null;
        if ("201000".equals(charge)){
            //如果课程免费，会向选课记录表，我的课程表写数据
            //向选课记录表写
            xcChooseCourse = addFreeCourse(userId, coursepublish);
            //向我的课程表写
            XcCourseTables xcCourseTables = addCourseTables(xcChooseCourse);

        }else {
            //如果课程收费，会向选课表写入数据
            xcChooseCourse = addChargeCourse(userId, coursepublish);

        }
        //判断学生的学习资格
        XcCourseTablesDto xcCourseTablesDto = getLearningStatus(userId, courseId);

        //构造返回值
        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(xcChooseCourse,xcChooseCourseDto);
        //设置学习资格状态
        xcChooseCourseDto.setLearnStatus(xcCourseTablesDto.getLearnStatus());

        return xcChooseCourseDto;
    }

    /**
     * 返回：学习资格，[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}]
     * @param userId
     * @param courseId
     * @return
     */
    @Override
    public XcCourseTablesDto getLearningStatus(String userId, Long courseId) {

        XcCourseTablesDto xcCourseTablesDto = new XcCourseTablesDto();

        //查询我的课程表，如果查不到说明没选课
        XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId);
        if (xcCourseTables == null){
            //{"code":"702002","desc":"没有选课或选课后没有支付"}
            xcCourseTablesDto.setLearnStatus("702002");
            return xcCourseTablesDto;
        }

        //如果查到了，判断是否过期，如果过期不能继续学习，没有过期可以继续学习
        boolean before = xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now());
        if (before){
            //{"code":"702003","desc":"已过期需要申请续期或重新支付"}
            xcCourseTablesDto.setLearnStatus("702003");
            BeanUtils.copyProperties(xcCourseTables,xcCourseTablesDto);
            return xcCourseTablesDto;
        }else {
            //{"code":"702001","desc":"正常学习"}
            BeanUtils.copyProperties(xcCourseTables,xcCourseTablesDto);
            xcCourseTablesDto.setLearnStatus("702001");
            return xcCourseTablesDto;
        }
    }

    /**
     * 添加免费课程，免费课程加入选课记录表，我的课程表
     * @param userId
     * @param coursePublish
     * @return
     */
    @Override
    public XcChooseCourse addFreeCourse(String userId,CoursePublish coursePublish){
        //课程id
        Long courseId = coursePublish.getId();
        //判断，如果存在免费的客车记录且选课状态为成功，直接返回
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>().eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, courseId)
                .eq(XcChooseCourse::getOrderType, "700001") //免费课程
                .eq(XcChooseCourse::getStatus, "701001");   //选课成功
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(queryWrapper);
        if (xcChooseCourses.size() > 0){
            return xcChooseCourses.get(0);
        }
        //向选课记录表写数据
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(courseId);
        xcChooseCourse.setCourseName(coursePublish.getName());
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursePublish.getCompanyId());
        xcChooseCourse.setOrderType("700001"); //免费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setCoursePrice(coursePublish.getPrice());
        xcChooseCourse.setValidDays(365);
        xcChooseCourse.setStatus("701001"); //选课成功
        xcChooseCourse.setValidtimeStart(LocalDateTime.now()); //有效期的开始时间
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365)); //有效期的结束时间
        xcChooseCourse.setRemarks(coursePublish.getRemark());
        int insert = xcChooseCourseMapper.insert(xcChooseCourse);
        if (insert <= 0){
            OnlinecClassroomException.cast("选课记录添加失败！");
        }

        return xcChooseCourse;
    }

    /**
     * 添加收费课程
     * @param userId
     * @param coursePublish
     * @return
     */
    private XcChooseCourse addChargeCourse(String userId,CoursePublish coursePublish){
        //课程id
        Long courseId = coursePublish.getId();
        //判断，如果存在收费的选课记录且选课状态为待支付，直接返回
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>().eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, courseId)
                .eq(XcChooseCourse::getOrderType, "700002") //收费课程
                .eq(XcChooseCourse::getStatus, "701002");   //待支付
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(queryWrapper);
        if (xcChooseCourses.size() > 0){
            return xcChooseCourses.get(0);
        }
        //向选课记录表写数据
        XcChooseCourse xcChooseCourse = new XcChooseCourse();

        xcChooseCourse.setCourseId(courseId);
        xcChooseCourse.setCourseName(coursePublish.getName());
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursePublish.getCompanyId());
        xcChooseCourse.setOrderType("700002"); //收费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setCoursePrice(coursePublish.getPrice());
        xcChooseCourse.setValidDays(365);
        xcChooseCourse.setStatus("701002"); //待支付
        xcChooseCourse.setValidtimeStart(LocalDateTime.now()); //有效期的开始时间
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365)); //有效期的结束时间
        xcChooseCourse.setRemarks(coursePublish.getRemark());
        int insert = xcChooseCourseMapper.insert(xcChooseCourse);
        if (insert <= 0){
            OnlinecClassroomException.cast("选课记录添加失败！");
        }
        return xcChooseCourse;
    }

    /**
     * 添加到我的课程表
     * @param xcChooseCourse
     * @return
     */
    @Override
    public XcCourseTables addCourseTables(XcChooseCourse xcChooseCourse){
        //选课成功了才能向我的课程表添加
        String status = xcChooseCourse.getStatus();
        if (!"701001".equals(status)){
            OnlinecClassroomException.cast("选课没有成功无法添加到课程表！");
        }
        //userId和课程id
        String userId = xcChooseCourse.getUserId();
        Long courseId = xcChooseCourse.getCourseId();
        XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId);
        if (xcCourseTables != null){
            return xcCourseTables;
        }
        xcCourseTables = new XcCourseTables();
        BeanUtils.copyProperties(xcChooseCourse,xcCourseTables);
        //记录选课表的主键
        xcCourseTables.setChooseCourseId(xcChooseCourse.getId());
        //选课类型
        xcCourseTables.setCourseType(xcChooseCourse.getOrderType());
        xcCourseTables.setUpdateDate(LocalDateTime.now());
        int insert = xcCourseTablesMapper.insert(xcCourseTables);
        if (insert <= 0){
            OnlinecClassroomException.cast("添加我的课程表失败！");
        }
        return xcCourseTables;
    }

    @Override
    public PageResult<XcCourseTables> mycourseTables(MyCourseTableParams params) {
        //用户id
        String userId = params.getUserId();
        //当前页码
        int page = params.getPage();
        //每页记录数
        int size = params.getSize();
        Page<XcCourseTables> xcCourseTablesPage = new Page<>(page,size);
        LambdaQueryWrapper<XcCourseTables> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XcCourseTables::getUserId,userId);

        //查询数据
        Page<XcCourseTables> result = xcCourseTablesMapper.selectPage(xcCourseTablesPage, queryWrapper);

        //数据列表
        List<XcCourseTables> records = result.getRecords();
        //数据总数
        long total = result.getTotal();

        //List<T> items, long counts, long page, long pageSize
        PageResult<XcCourseTables> pageResult = new PageResult<>(records,total,page,size);

        return pageResult;
    }

    /**
     * 根据课程和用户查询我的课程表中某一门课程
     * @param userId
     * @param courseId
     * @return
     */
    private XcCourseTables getXcCourseTables(String userId,Long courseId){
        LambdaQueryWrapper<XcCourseTables> queryWrapper = new LambdaQueryWrapper<XcCourseTables>()
                .eq(XcCourseTables::getUserId, userId)
                .eq(XcCourseTables::getCourseId, courseId);
        XcCourseTables xcCourseTables = xcCourseTablesMapper.selectOne(queryWrapper);
        return xcCourseTables;
    }
}
